package cn.bzc.data.process.infra.log;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.serializer.SerializerFeature;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import java.io.BufferedReader;
import java.io.IOException;
import java.util.Arrays;
import java.util.Map;

/**
 * SpringBoot AOP打印请求参数与响应参数
 */
@Aspect
@Order(5)
@Component
public class ControllerLogAspect {

    private static final Logger logger = LoggerFactory.getLogger(ControllerLogAspect.class);

    @Pointcut("execution(public * cn.archforce.investment.education.controller..*.*(..))")
    private void controllerLog() {
    }


    // 切点实现
    @Around("controllerLog()")
    public Object doAround(ProceedingJoinPoint pjp) throws Throwable {
        // 1.请求处理
        RequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes();
        ServletRequestAttributes servletRequestAttributes = (ServletRequestAttributes) requestAttributes;
        assert servletRequestAttributes != null;
        HttpServletRequest request = servletRequestAttributes.getRequest();
        String uri = request.getRequestURI();
        // 获取请求方式
        String method = request.getMethod();
        // GET
        if ("GET".equals(method)) {
            StringBuilder stringBuilder = new StringBuilder();
            // request.getParameterMap()只能获取Get方式传入的数据
            Map<String, String[]> parameterMap = request.getParameterMap();
            for (Map.Entry<String, String[]> entry : parameterMap.entrySet()) {
                stringBuilder.append(entry.getKey()).append(" - ").append(Arrays.toString(entry.getValue())).append("\n");
            }
            // 去掉最后一个多余的回车符
            if(stringBuilder.length() > 0) {
                stringBuilder.deleteCharAt(stringBuilder.length()-1);
            }
            logger.info(">> | 请求开始,URI: '{}', method: '{}', Data:\n{}", uri, method, stringBuilder);
        }
        // POST
        if ("POST".equals(method)) {
            try (BufferedReader bufferedReader = new BufferedReader(request.getReader())) {
                // 每次读取一行
                StringBuilder stringBuilder = new StringBuilder();
                String str;
                while ((str = bufferedReader.readLine()) != null) {
                    stringBuilder.append(str);
                }
                // 美化下stringBuilder这个json字符串的格式
                String prettyJsonStr = JSON.toJSONString(JSON.parseObject(stringBuilder.toString()), SerializerFeature.PrettyFormat, SerializerFeature.WriteMapNullValue, SerializerFeature.WriteDateUseDateFormat);
                logger.info(">> | 请求开始,URI: '{}', method: '{}', Data:\n{}", uri, method, prettyJsonStr);
            } catch (IOException e) {
                logger.error("Post参数请求解析失败:{}", e.getMessage());
            }
        }

        // 2.返回处理
        Object result = pjp.proceed();
        logger.info("<< | 请求结束,controller返回值:{}\n", JSON.toJSON(result));
        return result;
    }
}

